package com.zyh.em.evaluate;

import com.zyh.em.entity.EvaluateData;
import com.zyh.em.entity.EvaluateReport;
import com.zyh.em.entity.HistoryData;

import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 登录习惯评估
 */
public class HabitEvaluate extends AbstractEvaluate{

    private int thresholdCount;//达到这个值，才认定登录习惯已经养成

    public HabitEvaluate(int thresholdCount) {
        this.thresholdCount = thresholdCount;
    }

    @Override
    public void evaluate(EvaluateData evaluateData, HistoryData historyData, EvaluateReport evaluateReport, EvaluateChain evaluateChain) {
        long time = evaluateData.getTime();

        //Map<星期,Map<小时,登录次数>>
        Map<String, Map<String, Integer>> habits = historyData.getHabits();

        //通过habits计算用户累计登录次数
        Integer count = habits
                .values()
                .stream()
                .map(map -> map.values())
                .map(collection -> collection
                        .stream()
                        .reduce((v1, v2) -> v1 + v2))
                .map(optional -> optional.get())
                .reduce((v1, v2) -> v1 + v2)
                .orElse(0);//获取结果，如果结果为null则返回0

        if(count<thresholdCount){
            //认定登录习惯还没有养成
            //认定没有风险
            evaluateReport.setRiskFactor("habit",false);
        }else{
            //从time中获取到星期以及小时；通过Calender完成的
            Calendar instance = Calendar.getInstance();
            instance.setTimeInMillis(time);
            //星期
            String day = instance.get(Calendar.DAY_OF_WEEK)+"";
            //小时
            String hour = instance.get(Calendar.HOUR_OF_DAY)+"";

            if(habits.containsKey(day)){
                //包含星期
                Map<String, Integer> map = habits.get(day);
                if(map.containsKey(hour)){
                    //包含小时
                    Integer countForHour = map.get(hour);

                    //获取到map中的所有value,按照升序排列，取三分之二位置处的值作为阈值
                    List<Integer> list = map.values().stream().sorted().collect(Collectors.toList());
                    Integer threshold = list.get(list.size() * 2 / 3);

                    /**
                     * - 获取到小时对应的登录次数
                     * - 获取到该星期几，每一个小时的登录次数，按照升序进行排列。取三分之二位置处的值作为阈值
                     埋伏还是陷阱
                     * - 登录次数如果大于阈值，就认定符合用户的登录习惯；否则，不符合用户的登录习惯
                     */
                    evaluateReport.setRiskFactor("habit",countForHour<=threshold);

                }else{
                    //评估数据中对应的小时，在历次成功登录时没有登录过。不符合用户的登录习惯
                    evaluateReport.setRiskFactor("habit",true);

                }
            }else{
                //评估数据中对应的星期几，在历次成功登录时没有登录过。不符合用户的登录习惯
                evaluateReport.setRiskFactor("habit",true);
            }

        }


        evaluateChain.doEvaluate(evaluateData, historyData, evaluateReport);
    }
}
